package com.cutter.util;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class FFmpegMerge {
    private static final String videoTextName = "videoList";
    private static final String delimiter = "_";
    private static final String infoFileSuffix = ".txt";
    private static final String ffmpegPath = "F:\\Environment\\ffmpeg\\bin\\ffmpeg.exe";
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static String makeVideosNameFile(List<String> files,String path,int number){
        File file = getUniqueFile(path, videoTextName, number,infoFileSuffix);
        if (file==null){return null;}
        try (FileWriter writer = new FileWriter(file);){
            files.forEach(
                    (f)->{try {
                            writer.write("file "+"'"+f+"'\n");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
            );
        }catch (Exception e){
            e.printStackTrace();
        }
        return file.getAbsolutePath();
    }
    public static String mergeDirect(String sourceList,String path,String name,int n){
        File file = getUniqueFile(path, name, n,".mp4");
        String cmdFormat = "%s -f concat -safe 0 -i %s -c copy %s";
        String cmd = String.format(cmdFormat, ffmpegPath, sourceList, file.getAbsolutePath());
        execCommand(cmd);
        return file.getName();
    }
    // /b/a/xxxx0
    private static File getUniqueFile(String path, String name, int n,String suffix){
        File p = new File(path);
        Set<String> set = new HashSet<>();
        if (p.exists()&&p.isDirectory()){
            File[] files = p.listFiles();
            if (files!=null&&files.length>0){
                set = Arrays.stream(files).map(File::getName).collect(Collectors.toSet());
            }
        }else {
            return null;
        }
        int tmp=n;
        String name1 = name+delimiter+tmp+suffix;
        while (set.contains(name1)){
            name1 = name + delimiter + (++tmp)+suffix;
        }
        return new File(path+"\\"+name1);
    }




    public static String mergeVideo(List<String> list, String outputDir, String outputFile) {
        try {
            String format1 = "%s -i %s -c copy -bsf:v h264_mp4toannexb -f mpegts %s";
            String command1 = String.format(format1, ffmpegPath, list.get(0), outputDir + "input1.ts");
            String command2 = String.format(format1, ffmpegPath, list.get(1), outputDir + "input2.ts");

            String format3 = "%s -i \"concat:%s|%s\" -c copy -bsf:a aac_adtstoasc -movflags +faststart %s";
            String command3 = String.format(format3, ffmpegPath, outputDir + "input1.ts", outputDir + "input2.ts", outputFile);

            if (execCommand(command1) > 0 && execCommand(command2) > 0 && execCommand(command3) > 0) {
                File file1 = new File(outputDir + "input1.ts");
                File file2 = new File(outputDir + "input2.ts");
                file1.delete();
                file2.delete();
                return "1";
            } else {
                return "0";
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("-----合并失败!!!!!!" + outputFile);
            return "0";
        }
    }

    private static Integer execCommand(String command) {
        try {
            Process process = Runtime.getRuntime().exec(command);
            //获取进程的标准输入流
            final InputStream is1 = process.getInputStream();
            //获取进城的错误流
            final InputStream is2 = process.getErrorStream();
            //启动两个线程，一个线程负责读标准输出流，另一个负责读标准错误流
            readInputStream(is1);
            readInputStream(is2);
            process.waitFor();
            process.destroy();
            System.out.println("-----操作成功" + command + " " + sdf.format(new Date()));
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("-----操作失败" + command);
            return -1;
        }
    }

    private static void readInputStream(InputStream inputStream) {
        new Thread(() -> {
            BufferedReader br1 = new BufferedReader(new InputStreamReader(inputStream));
            try {
                String line1 = null;
                while ((line1 = br1.readLine()) != null) {
                    if (line1 != null) {
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

